﻿using System;
using System.Collections.Generic;
using System.Linq;
using SlamCms.Common;
using SlamCms.Configuration;

namespace SlamCms.Data
{
	public static class UserExtensions
	{
		public static bool IsAdministrator(this User user)
		{
			// This check is for the case when the user is not authenticated mostly
			if (user == null)
				return false;

			return user.Groups.Any(g => g.Edit);	
		}

	    public static bool IsContentExpirationAdmin(this User user)
        {
            var contentExpirationManagerGroups = ConfigurationManager.Environment.Settings.Get<string>(Constants.Settings.ContentExpirationManagerGroups);

            var managerGroupIds = new List<int>();
            if (!contentExpirationManagerGroups.IsNullOrEmpty())
                managerGroupIds.AddRange(contentExpirationManagerGroups.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)));

            return !managerGroupIds.Any() || user.Groups.Any(g => g.GroupId.In(managerGroupIds));
        }

		public static bool CanAdd(this User user, ContentItem contentItem)
		{
			return user.Can(g => g.Add, contentItem);
		}

		public static bool CanApprove(this User user, ContentItem contentItem)
		{
			return user.Can(g => g.Approve, contentItem);
		}

		public static bool CanEdit(this User user, ContentItem contentItem)
		{
			return user.Can(g => g.Edit, contentItem);
		}

		public static bool CanDelete(this User user, ContentItem contentItem)
		{
			return user.Can(g => g.Delete, contentItem);
		}

		public static bool CanView(this User user, ContentItem contentItem)
		{
			return user.Can(g => g.View, contentItem);
		}

		private static bool Can(this User user, Predicate<Group> predicate, ContentItem contentItem)
		{
			// This check is for the case when the user is not authenticated mostly
			if (user == null)
				return false;

			Ensure.ArgumentNotNull(predicate, "predicate");
			Ensure.ArgumentNotNull(contentItem, "contentItem");
			Ensure.ArgumentNotNull(contentItem.List, "contentItem", "The List property is null");
			
			var siteId = contentItem.List.SiteId;
			return user.Groups.Any(g => predicate(g) && g.Sites.Any(s => s.SiteId == siteId));
		}
	}
}
